import { Scope } from "../typings/traverse";

/**
 * 处理v-attr :attr
 * @param _attr 属性的值
 * 将attr["key"]转换为attr.key
 */
function preResAttributeLoad(_attr: string) {
  let attr: string = _attr.trim();
  if (attr[0] == "'" || attr[0] == '"') {
  } else {
    attr = attr.replace(/\[/g, ".").replace(/[\]"']/g, "");
  }
  return attr;
}

function checkNamespace(goal: string, item: string) {
  if (goal.split(".").shift() == item) {
    return true;
  } else {
    return false;
  }
}
/**
 *
 * @param items scope.items
 * @param item scope.item
 * @param variate 例如v-text="obj.a"这个obj.a就是variate
 */
function absolutePath(items: string, item: string, variate: string) {
  let key = variate.replace(item, "");
  return items + key;
}

/**
 * 因为交互指令有两种写法，所以在这里处理
 * @param element
 * @param interactive
 */
function getInteractiveAttribute(
  element: Element,
  interactive: string
): string | null {
  if (element.hasAttribute(`@${interactive}`)) {
    return element.getAttribute(`@${interactive}`);
  } else if (element.hasAttribute(`v-on:${interactive}`)) {
    return element.getAttribute(`v-on:${interactive}`);
  } else if (element.hasAttribute(`@${interactive}.native`)) {
    return element.getAttribute(`@${interactive}.native`);
  } else if (element.hasAttribute(`v-on:${interactive}.native`)) {
    return element.getAttribute(`v-on:${interactive}.native`);
  } else {
    return null;
  }
}

/**
 * 可以匹配到函数名
 * functionName($event, item)
 * -> 'functionName'
 */
function parseFunctionName(str: string): string {
  return str.replace(/\(.+\)/g, "");
}
/**
 * 可以匹配到括号里的字符串
 * functionName(item)
 * functionName($event, item)
 * -> ['item']和['$event', 'item']
 */
function parseFunctionArgvs(str: string): Array<string> | undefined {
  let match = str.match(/(?<=\().+(?=\))/g);
  let argvs: Array<string> | undefined;
  if (match) {
    argvs = match[0].split(",").map((argv) => {
      return preResAttributeLoad(argv.trim());
    });
  }
  return argvs;
}

/**
 * 
 * @param scope 作用域
 * @param path element上取下了属性值
 * 引入作用域scope后，属性值不应该直接调用getGoalData去查找数据
 */
function getCorrectedPath(path: string, scope?: Scope) {
  let correctPath: string = preResAttributeLoad(path);
  if (scope) {
    const { item, items } = scope;
    let isPropNamespace = checkNamespace(correctPath, item);
    if (isPropNamespace) {
      correctPath = absolutePath(items, item, correctPath);
    }
  }
  return correctPath;
}

export {
  checkNamespace,
  absolutePath,
  getInteractiveAttribute,
  parseFunctionName,
  parseFunctionArgvs,
  preResAttributeLoad,
  getCorrectedPath
};
